package org.xtframe.sql;

import java.util.ArrayList;
import java.util.List;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.xtframe.common.SimpleFormat;
import org.xtframe.util.CommonUtil;
import org.xtframe.util.SpringUtil;
import org.xtframe.util.StringUtil;

public class SqlDataVerify {
	
	// Sql校验类型（替换、检查）
	public enum VerifyType {
		replace, check
	}
	
	private static final String BASE = "base";

	private int count = -1;
	
	private int[] safePositions = null;
	
	private List<VerifyBase> dataVerifyList = new ArrayList<VerifyBase>();
	
	public SqlDataVerify(String pattern){
		JSONArray list = CommonUtil.getJSONArray(pattern);
		if(list != null){
			for(int i=0; i<list.size(); i++){
				JSONObject o = list.optJSONObject(i);
				if(o != null){
					if(o.has("vtype")){
						if(BASE.equals(o.optString("vtype"))){
							if(o.has("count")){
								this.count = o.optInt("count");
							}
							if(o.has("safes")){
								JSONArray safes = o.getJSONArray("safes");
								this.safePositions = new int[safes.size()];
								for(int k=0; k<safes.size(); k++)
									this.safePositions[k] = safes.optInt(k);
							}
						} else {
							SqlDataVerifyFactory sqlDataVerifyFactory = (SqlDataVerifyFactory) SpringUtil.getBean("sqlDataVerifyFactory");
							VerifyBase verifyBase = sqlDataVerifyFactory.getVerifyBase(o.optString("vtype"));
							verifyBase.init(o);
							if(verifyBase != null) dataVerifyList.add(verifyBase);
						}
					}
				}
			}
		}
	}
	
	private boolean verify(List<String> parameters, List<PreparedParameter> preparedParameters){
		if(count!=-1 && count!=parameters.size()) return false;
		for(VerifyBase verifyBase : dataVerifyList){
			if (verifyBase.getXtype() == VerifyType.replace) {
				parameters.set(verifyBase.getPosition(), verifyBase.replace(parameters, preparedParameters));
			} else if (verifyBase.getXtype() == VerifyType.check) {
				if(!verifyBase.check(parameters)) return false;
			} else {
				return false;
			}
		}
		return true;
	}
	
	public SqlData createSql(String sqlMode, List<String> parameters){
		SqlData sqlData = new SqlData();
		List<PreparedParameter> preparedParameters = new ArrayList<PreparedParameter>();
		if(verify(parameters, preparedParameters)){
			boolean flag = true;
			for (int i = 0; i < parameters.size(); i++) {
				if(safePositions != null){
					flag = true;
					for(int j : safePositions){
						if(j == i){
							flag = false;
							break;
						}
					}
					if(!flag) continue;
				}
				parameters.set(i, StringUtil.replaceSql(parameters.get(i)));
			}
			sqlData.setPreparedParameters(preparedParameters);
			sqlData.setSql(SimpleFormat.format(sqlMode, parameters.toArray()));
			sqlData.setResult(true);
		} else {
			sqlData.setResult(false);
		}
		return sqlData;
	}
}
